home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / Python 133 SRC / Extensions / img / imgjpegmodule.c < prev    next >
Text File  |  1995-12-21  |  19KB  |  692 lines

  1. /***********************************************************
  2. Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
  3. Amsterdam, The Netherlands.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its 
  8. documentation for any purpose and without fee is hereby granted, 
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in 
  11. supporting documentation, and that the names of Stichting Mathematisch
  12. Centrum or CWI not be used in advertising or publicity pertaining to
  13. distribution of the software without specific, written prior permission.
  14.  
  15. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
  16. THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17. FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
  18. FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19. WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  20. ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  21. OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  
  23. ******************************************************************/
  24.  
  25. /*
  26. ** This module is only half-finished, really.
  27. ** It reads the jpeg file immedeately upon opening it, mainly because there
  28. ** is no official interface to the jpeg library that allows you to read
  29. ** the header first and the rest of the data later.
  30. ** Also, it does not provide any access to all sorts of jpeg parameters,
  31. ** like quality, etc.
  32. */
  33.  
  34. #include "jinclude.h"
  35. #include <setjmp.h>
  36. static jmp_buf setjmp_buffer;
  37. static external_methods_ptr emethods;
  38. char jpegmsgbuf[256];
  39.  
  40. /* Jpeg objects */
  41.  
  42. #include "Python.h"
  43. #include "import.h"
  44.  
  45. /* XXXX change this to the image formats we support */
  46.  
  47. static PyObject *format_rgb, *format_rgb_b2t, *format_grey, *format_grey_b2t;
  48. extern PyObject *getimgformat();    /* Get format by name */
  49.  
  50. typedef struct {
  51.     PyObject_HEAD
  52.     PyObject    *dict;        /* Attributes dictionary */
  53.     int    is_reader;    /* TRUE if this is a reader */
  54.     char    *filename;    /* filename of the image file */
  55.     PyObject    *data_read;    /* The data being read */
  56.     char    *data_ptr;    /* Where we are reading now */
  57.     int    is_grey;    /* True if grey data being read */
  58.     int    rowlen;        /* Length of a row */
  59.     /* Add other (user-invisible) data here */
  60. } jpegobject;
  61.  
  62. static PyObject *errobject;
  63.  
  64. staticforward PyTypeObject Jpegtype;
  65.  
  66. #define is_jpegobject(v)        ((v)->ob_type == &Jpegtype)
  67.  
  68. static char doc_jpeg[] = "This object reads or writes a JPEG file.\n"
  69.     "The 'width', 'height' and 'format' attributes describe the data.\n"
  70.     "In writer objects you can set 'quality' to a value from 0-100";
  71.  
  72. /* Jpeg error handling. */
  73. METHODDEF void
  74. jpeg_trace_message (const char *msgtext)
  75. {
  76.   sprintf(jpegmsgbuf, msgtext,
  77.       emethods->message_parm[0], emethods->message_parm[1],
  78.       emethods->message_parm[2], emethods->message_parm[3],
  79.       emethods->message_parm[4], emethods->message_parm[5],
  80.       emethods->message_parm[6], emethods->message_parm[7]);
  81. }
  82.  
  83. METHODDEF void
  84. jpeg_error_exit (const char *msgtext)
  85. {
  86.   jpeg_trace_message(msgtext);    /* report the error message */
  87.   (*emethods->free_all) ();    /* clean up memory allocation & temp files */
  88.   PyErr_SetString(errobject, jpegmsgbuf);
  89.   longjmp(setjmp_buffer, 1);    /* return control to outer routine */
  90. }
  91.  
  92. METHODDEF void
  93. jpeg_my_error_exit ()
  94. {
  95.   (*emethods->free_all) ();    /* clean up memory allocation & temp files */
  96.   longjmp(setjmp_buffer, 1);    /* return control to outer routine */
  97. }
  98.  
  99. /* Helper routines for the JPEG reader */
  100. METHODDEF void
  101. output_init (decompress_info_ptr cinfo)
  102. /* This routine should do any setup required */
  103. {
  104.     PyObject *dp;
  105.     jpegobject *self;
  106.     int wantgrey, w, h, rowlen, size;
  107.  
  108.     self = (jpegobject *)cinfo->output_file;
  109.     w = cinfo->image_width;
  110.     h = cinfo->image_height;
  111.     jpegsetintattr(self, "width", w);
  112.     jpegsetintattr(self, "height", h);
  113.     wantgrey = (cinfo->final_out_comps == 1);
  114.     if ( wantgrey ) {
  115.     PyDict_SetItemString(self->dict, "format", format_grey);
  116.     PyDict_SetItemString(self->dict, "format_choices", Py_BuildValue("(O)", format_grey));
  117.     rowlen = (w+3) & ~3;
  118.     size = rowlen*h;
  119.     } else {
  120.     PyDict_SetItemString(self->dict, "format", format_rgb);
  121.     PyDict_SetItemString(self->dict, "format_choices", Py_BuildValue("(O)", format_rgb));
  122.     rowlen = w;
  123.     size = rowlen*h*4;
  124.     }
  125.     dp = PyString_FromStringAndSize(NULL, size);
  126.     if( PyErr_Occurred() || dp == NULL )
  127.     jpeg_my_error_exit();
  128.     
  129.     self->data_read = dp;
  130.     self->is_grey = wantgrey;
  131.     self->data_ptr = PyString_AsString(dp);
  132.     self->rowlen = rowlen;
  133. }
  134.  
  135. METHODDEF void
  136. put_color_map (decompress_info_ptr cinfo, int num_colors, JSAMPARRAY colormap)
  137. /* Write the color map */
  138. {
  139.   jpeg_error_exit("put_color_map called: there's a bug here somewhere!");
  140. }
  141.  
  142. METHODDEF void
  143. put_pixel_rows (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE pixel_data)
  144. /* Write some rows of output data */
  145. {
  146.   jpegobject *jp = (jpegobject *)cinfo->output_file;
  147.   PyObject *dp = jp->data_read;
  148.   char *greydata = jp->data_ptr;
  149.   JSAMPROW ptr0, ptr1, ptr2;
  150.   long col;
  151.   int row;
  152.   long *rgbdata;
  153.   int r, g, b;
  154.   int rowlen = jp->rowlen;
  155.  
  156.   if ( jp->is_grey ) {
  157.       for (row=0; row < num_rows; row++) {
  158.       ptr0 = pixel_data[0][row];
  159.       for (col=0; col<cinfo->image_width; col++) {
  160.           *greydata++ = GETJSAMPLE(*ptr0);
  161.           ptr0++;
  162.       }
  163.       while( col < rowlen ) {
  164.           *greydata++ = 0;
  165.           col++;
  166.       }
  167.       }
  168.       jp->data_ptr = greydata;
  169.   } else {
  170.       rgbdata = (long *)greydata;
  171.       for (row=0; row < num_rows; row++) {
  172.       ptr0 = pixel_data[0][row];
  173.       ptr1 = pixel_data[1][row];
  174.       ptr2 = pixel_data[2][row];
  175.       for (col=0; col<cinfo->image_width; col++) {
  176.           r = GETJSAMPLE(*ptr0);
  177.           g = GETJSAMPLE(*ptr1);
  178.           b = GETJSAMPLE(*ptr2);
  179.           ptr0++; ptr1++; ptr2++;
  180.           *rgbdata++ = r | (g << 8) | (b<<16);
  181.       }
  182.       }
  183.       jp->data_ptr = (char *)rgbdata;
  184.   }
  185. }
  186.  
  187.  
  188. METHODDEF void
  189. output_term (decompress_info_ptr cinfo)
  190. /* Finish up at the end of the output */
  191. {
  192. }
  193.  
  194. METHODDEF void
  195. d_ui_method_selection (decompress_info_ptr cinfo)
  196. {
  197.   /* if grayscale input, force grayscale output; */
  198.   /* else leave the output colorspace as set by main routine. */
  199.   if (cinfo->jpeg_color_space == CS_GRAYSCALE)
  200.     cinfo->out_color_space = CS_GRAYSCALE;
  201.  
  202.   /* select output routines */
  203.   cinfo->methods->output_init = output_init;
  204.   cinfo->methods->put_color_map = put_color_map;
  205.   cinfo->methods->put_pixel_rows = put_pixel_rows;
  206.   cinfo->methods->output_term = output_term;
  207. }
  208.  
  209. /* JPEG writer helper routines */
  210. METHODDEF void
  211. input_init (compress_info_ptr cinfo)
  212. /* Initialize for input; return image size and component data. */
  213. {
  214. }
  215.  
  216. METHODDEF void
  217. get_input_row (compress_info_ptr cinfo, JSAMPARRAY pixel_row)
  218. /* Read next row of pixels into pixel_row[][] */
  219. {
  220.   register FILE * infile = cinfo->input_file;
  221.   jpegobject *self = (jpegobject *)cinfo->input_file;
  222.   char *greydata = self->data_ptr;
  223.   long *rgbdata;
  224.   JSAMPROW ptr0, ptr1, ptr2;
  225.   long col;
  226.   long rgb;
  227.  
  228.   if ( self->is_grey ) {
  229.       ptr0 = pixel_row[0];
  230.       for (col=0; col < cinfo->image_width; col++)
  231.       *ptr0++ = *greydata++;
  232.       while ( col < self->rowlen ) {
  233.       col++;
  234.       greydata++;
  235.       }
  236.       self->data_ptr = greydata;
  237.   } else {
  238.       rgbdata = (long *)greydata;
  239.       ptr0 = pixel_row[0];
  240.       ptr1 = pixel_row[1];
  241.       ptr2 = pixel_row[2];
  242.       for (col = 0; col < cinfo->image_width; col++) {
  243.       rgb = *rgbdata++;
  244.       *ptr0++ = (JSAMPLE) (rgb & 0xff);
  245.       *ptr1++ = (JSAMPLE) ((rgb>>8) & 0xff);
  246.       *ptr2++ = (JSAMPLE) ((rgb>>16) & 0xff);
  247.       }
  248.       self->data_ptr = (char *)rgbdata;
  249.   }
  250. }
  251.  
  252.  
  253.  
  254. METHODDEF void
  255. input_term (compress_info_ptr cinfo)
  256. /* Finish up at the end of the input */
  257. {
  258. }
  259.  
  260. METHODDEF void
  261. c_ui_method_selection (compress_info_ptr cinfo)
  262. {
  263.   /* If the input is gray scale, generate a monochrome JPEG file. */
  264.   if (cinfo->in_color_space == CS_GRAYSCALE)
  265.     j_monochrome_default(cinfo);
  266.   /* For now, always select JFIF output format. */
  267.   jselwjfif(cinfo);
  268. }
  269.  
  270. /* Routine to easily obtain C data from the dict python data */
  271. int
  272. jpegselfattr(self, name, fmt, ptr, wanterr)
  273.     jpegobject *self;
  274.     char *name;
  275.     char *fmt;
  276.     void *ptr;
  277.     int wanterr;
  278. {
  279.     PyObject *obj;
  280.     char errbuf[100];
  281.  
  282.     obj = PyDict_GetItemString(self->dict, name);
  283.     if ( obj == NULL ) {
  284.     if ( wanterr ) {
  285.         sprintf(errbuf, "Required attribute '%s' not set", name);
  286.         PyErr_SetString(errobject, errbuf);
  287.         return 0;
  288.     } else {
  289.         PyErr_Clear();
  290.         return 0;
  291.     }
  292.     }
  293.     if ( !PyArg_Parse(obj, fmt, ptr) ) {
  294.     if ( !wanterr )
  295.         PyErr_Clear();
  296.     return 0;
  297.     }
  298.     return 1;
  299. }
  300.  
  301. /* Routine to easily insert integer into dictionary */
  302. jpegsetintattr(self, name, value)
  303.     jpegobject *self;
  304.     char *name;
  305.     int value;
  306. {
  307.     PyObject *obj;
  308.     int rv;
  309.  
  310.     obj = PyInt_FromLong(value);
  311.     rv = PyDict_SetItemString(self->dict, name, obj);
  312.     Py_DECREF(obj);
  313.     return rv;
  314. }
  315.  
  316. static jpegobject *
  317. newjpegobject()
  318. {
  319.     jpegobject *xp;
  320.     xp = PyObject_NEW(jpegobject, &Jpegtype);
  321.     if (xp == NULL)
  322.         return NULL;
  323.     xp->dict = PyDict_New();
  324.     xp->filename = NULL;
  325.     xp->data_read = NULL;
  326.     return xp;
  327. }
  328.  
  329. static int
  330. initjpegreader(self, name)
  331.     jpegobject *self;
  332.     char *name;
  333. {
  334.     char *name_copy;
  335.     struct Decompress_info_struct cinfo;
  336.     struct Decompress_methods_struct dc_methods;
  337.     struct External_methods_struct e_methods;
  338.  
  339.     memset((char *)&cinfo, 0, sizeof cinfo);
  340.     memset((char *)&dc_methods, 0, sizeof dc_methods);
  341.     memset((char *)&e_methods, 0, sizeof e_methods);
  342.     if( (name_copy=malloc(strlen(name)+1)) == NULL ) {
  343.     PyErr_NoMemory();
  344.     return 0;
  345.     }
  346.     strcpy(name_copy, name);
  347.     self->filename = name_copy;
  348.     self->is_reader = 1;
  349.     if ((cinfo.input_file = fopen(name, "rb")) == NULL) {
  350.     PyErr_SetFromErrno(PyExc_IOError);
  351.     return 0;
  352.     }
  353.     cinfo.output_file = (FILE *)self;
  354.  
  355.     /* Initialize the system-dependent method pointers. */
  356.     cinfo.methods = &dc_methods;    /* links to method structs */
  357.     cinfo.emethods = &e_methods;
  358.     emethods = &e_methods;    /* save struct addr for possible access */
  359.     e_methods.error_exit = jpeg_error_exit; /* supply error-exit routine */
  360.     e_methods.trace_message = jpeg_trace_message; /* supply trace-message routine */
  361.     e_methods.trace_level = 0;    /* default = no tracing */
  362.     e_methods.num_warnings = 0;    /* no warnings emitted yet */
  363.     e_methods.first_warning_level = 0; /* display first corrupt-data warning */
  364.     e_methods.more_warning_level = 3; /* but suppress additional ones */
  365.  
  366.     if ( setjmp(setjmp_buffer) ) {
  367.     /* An error occurred */
  368.     return 0;
  369.     }
  370.     jselmemmgr(&e_methods);    /* select std memory allocation routines */
  371.     dc_methods.d_ui_method_selection = d_ui_method_selection;
  372.     j_d_defaults(&cinfo, TRUE);
  373.     jselrjfif(&cinfo);
  374.     jpeg_decompress(&cinfo);
  375.     fclose(cinfo.input_file);
  376.     return 1;
  377. }
  378.  
  379. static int
  380. initjpegwriter(self, name)
  381.     jpegobject *self;
  382.     char *name;
  383. {
  384.     char *name_copy;
  385.  
  386.     if( (name_copy=malloc(strlen(name)+1)) == NULL ) {
  387.     PyErr_NoMemory();
  388.     return 0;
  389.     }
  390.     strcpy(name_copy, name);
  391.     self->filename = name_copy;
  392.     self->is_reader = 0;
  393.     PyDict_SetItemString(self->dict, "format", format_rgb);
  394.     PyDict_SetItemString(self->dict, "format_choices",
  395.            Py_BuildValue("(OO)", format_rgb, format_grey));
  396.     if( PyErr_Occurred())
  397.     return 0;
  398.     return 1;
  399. }
  400.  
  401. /* Jpeg methods */
  402.  
  403. static void
  404. jpeg_dealloc(xp)
  405.     jpegobject *xp;
  406. {
  407.     Py_XDECREF(xp->dict);
  408.     if( xp->filename )
  409.         free(xp->filename);
  410.     if( xp->data_read )
  411.         Py_DECREF(xp->data_read);
  412.     /* XXXX Free other allocated things here */
  413.     PyMem_DEL(xp);
  414. }
  415.  
  416. static char doc_read[] = "Return the data read by this object";
  417.  
  418. static PyObject *
  419. jpeg_read(self, args)
  420.     jpegobject *self;
  421.     PyObject *args;
  422. {
  423.     
  424.     if (!PyArg_ParseTuple(args,""))
  425.         return NULL;
  426.     if (!self->is_reader) {
  427.         PyErr_SetString(errobject, "Cannot read() from writer object");
  428.         return NULL;
  429.     }
  430.     if (!self->data_read) {
  431.         PyErr_SetString(errobject, "Internal error: no data read!");
  432.         return NULL;
  433.     }
  434.     Py_INCREF(self->data_read);
  435.     return self->data_read;
  436. }
  437.  
  438. static char doc_write[] = "Write data to the JPEG file";
  439.  
  440. static PyObject *
  441. jpeg_write(self, args)
  442.     jpegobject *self;
  443.     PyObject *args;
  444. {
  445.         char *data;
  446.     int datalen;
  447.     PyObject *fmt;
  448.     int w, h, rowlen, wantgrey, size;
  449.     struct Compress_info_struct cinfo;
  450.     struct Compress_methods_struct c_methods;
  451.     struct External_methods_struct e_methods;
  452.     int quality = 75;
  453.     
  454.     memset((char *)&cinfo, 0, sizeof cinfo);
  455.     memset((char *)&c_methods, 0, sizeof c_methods);
  456.     memset((char *)&e_methods, 0, sizeof e_methods);
  457.     
  458.     if (!PyArg_ParseTuple(args, "s#", &data, &datalen))
  459.         return NULL;
  460.     if (self->is_reader) {
  461.         PyErr_SetString(errobject, "Cannot write() to reader object");
  462.         return NULL;
  463.     }
  464.     /* XXXX Get args from self->dict and write the data */
  465.     if ( !jpegselfattr(self, "width", "i", &w, 1) ||
  466.          !jpegselfattr(self, "height", "i", &h, 1) ||
  467.          !jpegselfattr(self, "format", "O", &fmt, 1) )
  468.         return NULL;
  469.     if ( fmt == format_rgb ) {
  470.         rowlen = w;
  471.         wantgrey = 0;
  472.         size = w*h*4;
  473.     } else {
  474.         rowlen = (w+3) & ~3;
  475.         wantgrey = 1;
  476.         size = rowlen*h;
  477.     }
  478.     if( size != datalen ) {
  479.         PyErr_SetString(errobject, "Incorrect datasize");
  480.         return NULL;
  481.     }
  482.     (void) jpegselfattr(self, "quality", "i", &quality, 0);
  483.     
  484.     self->data_ptr = data;
  485.     self->rowlen = rowlen;
  486.     self->is_grey = wantgrey;
  487.     /* Initialize the system-dependent method pointers. */
  488.     if ( setjmp(setjmp_buffer) ) {
  489.         /* An error occurred */
  490.         return NULL;
  491.     }
  492.     cinfo.methods = &c_methods;    /* links to method structs */
  493.     cinfo.emethods = &e_methods;
  494.     if ( (cinfo.output_file = fopen(self->filename, "wb")) == NULL ) {
  495.         PyErr_SetFromErrno(PyExc_IOError);
  496.         return NULL;
  497.     }
  498. #ifdef macintosh
  499.     setfiletype(self->filename, '????', 'JPEG');
  500. #endif
  501.     emethods = &e_methods;    /* save struct addr for possible access */
  502.     e_methods.error_exit = jpeg_error_exit; /* supply error-exit routine */
  503.     e_methods.trace_message = jpeg_trace_message; /* supply trace-message routine */
  504.     e_methods.trace_level = 0;    /* default = no tracing */
  505.     e_methods.num_warnings = 0;    /* no warnings emitted yet */
  506.     e_methods.first_warning_level = 0; /* display first corrupt-data warning */
  507.     e_methods.more_warning_level = 3; /* but suppress additional ones */
  508.     jselmemmgr(&e_methods);    /* select std memory allocation routines */
  509.     c_methods.input_init = input_init;
  510.     c_methods.get_input_row = get_input_row;
  511.     c_methods.input_term = input_term;
  512.     c_methods.c_ui_method_selection = c_ui_method_selection;
  513.     j_c_defaults(&cinfo, quality, FALSE);
  514.  
  515.     cinfo.image_width = w;        /* width in pixels */
  516.     cinfo.image_height = h;    /* height in pixels */
  517.     cinfo.input_file = (FILE *)self;
  518.     
  519.     if ( wantgrey ) {
  520.         cinfo.input_components = 1;
  521.         cinfo.in_color_space = CS_GRAYSCALE;
  522.     } else {
  523.         cinfo.input_components = 3;
  524.         cinfo.in_color_space = CS_RGB;
  525.     }
  526.     cinfo.data_precision = 8;
  527.     jpeg_compress(&cinfo);
  528.     fclose(cinfo.output_file);
  529.     Py_INCREF(Py_None);
  530.     return Py_None;
  531. }
  532.  
  533. static struct PyMethodDef jpeg_methods[] = {
  534.     {"read",    (PyCFunction)jpeg_read,        1,    doc_read},
  535.     {"write",    (PyCFunction)jpeg_write,    1,    doc_write},
  536.     {NULL,        NULL}        /* sentinel */
  537. };
  538.  
  539. static PyObject *
  540. jpeg_getattr(xp, name)
  541.     jpegobject *xp;
  542.     char *name;
  543. {
  544.         PyObject *v;
  545.     
  546.     if (xp->dict != NULL) {
  547.             if ( strcmp(name, "__dict__") == 0 ) {
  548.                 Py_INCREF(xp->dict);
  549.             return xp->dict;
  550.         }
  551.                if ( strcmp(name, "__doc__") == 0 ) {
  552.                 return PyString_FromString(doc_jpeg);
  553.         }
  554.         v = PyDict_GetItemString(xp->dict, name);
  555.         if (v != NULL) {
  556.             Py_INCREF(v);
  557.             return v;
  558.         }
  559.     }
  560.     return Py_FindMethod(jpeg_methods, (PyObject *)xp, name);
  561. }
  562.  
  563. static int
  564. jpeg_setattr(xp, name, v)
  565.     jpegobject *xp;
  566.     char *name;
  567.     PyObject *v;
  568. {
  569.     if (xp->dict == NULL) {
  570.         xp->dict = PyDict_New();
  571.         if (xp->dict == NULL)
  572.             return -1;
  573.     }
  574.     if (v == NULL) {
  575.         int rv = PyDict_DelItemString(xp->dict, name);
  576.         if (rv < 0)
  577.             PyErr_SetString(PyExc_AttributeError,
  578.                     "delete non-existing imgjpeg attribute");
  579.         return rv;
  580.     }
  581.     else
  582.         return PyDict_SetItemString(xp->dict, name, v);
  583. }
  584.  
  585. static PyTypeObject Jpegtype = {
  586.     PyObject_HEAD_INIT(&PyType_Type)
  587.     0,            /*ob_size*/
  588.     "imgjpeg",        /*tp_name*/
  589.     sizeof(jpegobject),    /*tp_basicsize*/
  590.     0,            /*tp_itemsize*/
  591.     /* methods */
  592.     (destructor)jpeg_dealloc, /*tp_dealloc*/
  593.     0,            /*tp_print*/
  594.     (getattrfunc)jpeg_getattr, /*tp_getattr*/
  595.     (setattrfunc)jpeg_setattr, /*tp_setattr*/
  596.     0,            /*tp_compare*/
  597.     0,            /*tp_repr*/
  598.     0,            /*tp_as_number*/
  599.     0,            /*tp_as_sequence*/
  600.     0,            /*tp_as_mapping*/
  601.     0,            /*tp_hash*/
  602. };
  603.  
  604. static char doc_newreader[] = "Return an object that reads a JPEG file.\n"
  605.     "Note that the actual data is read upon creation of the object.";
  606.  
  607. static PyObject *
  608. jpeg_newreader(self, args)
  609.     PyObject *self;
  610.     PyObject *args;
  611. {
  612.         char *filename;
  613.     jpegobject *obj;
  614.     
  615.     if (!PyArg_ParseTuple(args, "s", &filename))
  616.         return NULL;
  617.     if ((obj = newjpegobject()) == NULL)
  618.         return NULL;
  619.     if ( !initjpegreader(obj, filename) ) {
  620.         jpeg_dealloc(obj);
  621.         return NULL;
  622.     }
  623.     return (PyObject *)obj;
  624. }
  625.  
  626. static char doc_newwriter[] =
  627.     "Return an object that creates the JPEG file passed as argument";
  628.  
  629. static PyObject *
  630. jpeg_newwriter(self, args)
  631.     PyObject *self;
  632.     PyObject *args;
  633. {
  634.         char *filename;
  635.     jpegobject *obj;
  636.     
  637.     if (!PyArg_ParseTuple(args, "s", &filename))
  638.         return NULL;
  639.     if ((obj = newjpegobject()) == NULL)
  640.         return NULL;
  641.     if ( !initjpegwriter(obj, filename) ) {
  642.         jpeg_dealloc(obj);
  643.         return NULL;
  644.     }
  645.     return (PyObject *)obj;
  646. }
  647.  
  648.  
  649. /* List of functions defined in the module */
  650.  
  651. static struct PyMethodDef jpeg_module_methods[] = {
  652.     {"reader",    jpeg_newreader,    1,    doc_newreader},
  653.     {"writer",    jpeg_newwriter,    1,    doc_newwriter},
  654.     {NULL,        NULL}        /* sentinel */
  655. };
  656.  
  657.  
  658. /* Initialization function for the module (*must* be called initimgjpeg) */
  659. static char doc_imgjpeg[] =
  660.   "Module that reads and writes JPEG image files";
  661.  
  662. void
  663. initimgjpeg()
  664. {
  665.     PyObject *m, *d, *x, *formatmodule, *formatdict;
  666.  
  667.     /* Create the module and add the functions */
  668.     m = Py_InitModule("imgjpeg", jpeg_module_methods);
  669.  
  670.     /* Add some symbolic constants to the module */
  671.     d = PyModule_GetDict(m);
  672.     errobject = PyString_FromString("imgjpeg.error");
  673.     PyDict_SetItemString(d, "error", errobject);
  674.     x = PyString_FromString(doc_imgjpeg);
  675.     PyDict_SetItemString(d, "__doc__", x);
  676.  
  677.     /* Get supported formats */
  678.     if ((formatmodule = PyImport_ImportModule("imgformat")) == NULL)
  679.         Py_FatalError("imgjpeg depends on imgformat");
  680.     if ((formatdict = PyModule_GetDict(formatmodule)) == NULL)
  681.         Py_FatalError("imgformat has no dict");
  682.  
  683.     format_rgb = PyDict_GetItemString(formatdict,"rgb");
  684.     format_rgb_b2t = PyDict_GetItemString(formatdict,"rgb_b2t");
  685.     format_grey = PyDict_GetItemString(formatdict, "grey");
  686.     format_grey_b2t = PyDict_GetItemString(formatdict, "grey_b2t");
  687.  
  688.     /* Check for errors */
  689.     if (PyErr_Occurred())
  690.         Py_FatalError("can't initialize module imgjpeg");
  691. }
  692.